import os,json
from kubernetes import client, config
from kubernetes.client.rest import ApiException


config.load_kube_config(
    os.path.join(os.environ["HOME"], '.kube/config'))

class KubeJob:
    def __init__(self):
        self.batch_v1 = client.BatchV1Api()
    def create_job(self,job,namespace):
        try:
            resp = self.batch_v1.create_namespaced_job(body=job,namespace=namespace)
        except ApiException as e:
            return ("Exception when calling AppsV1Api->list_namespaced_deployment: %s\n" % e)
        return resp.status

def create_job_object(round_num,obj,node,task_name):

    env = [
        client.V1EnvVar(
            name='seq',
            value=str(round_num)),
        client.V1EnvVar(
            name='task',
            value=str(task_name)),
        client.V1EnvVar(
            name='uuid',
            value=str(obj.uuid))
    ]
    volume01 = client.V1Volume(
        name='data-storage',
        host_path=client.V1HostPathVolumeSource(path="/opt/train")
    )

    # Configureate Pod template container
    container = client.V1Container(
        name=node.hostname,
        image=obj.image,
        env=env,
        image_pull_policy="IfNotPresent",
        volume_mounts=[client.V1VolumeMount(name="data-storage", mount_path='/opt/train')],
        resources=client.V1ResourceRequirements(
            limits={"cpu": str(obj.pu) + "m", "memory": str(obj.ram) + "Mi"},
            requests={"cpu": "100m", "memory": "64Mi"},
        ),
    )
    affinity = client.V1Affinity(
                node_affinity=client.V1NodeAffinity(
                    required_during_scheduling_ignored_during_execution=client.V1NodeSelector(
                        node_selector_terms=[client.V1NodeSelectorTerm(
                            match_expressions=[client.V1NodeSelectorRequirement(
                                key='kubernetes.io/hostname', operator='In', values=[node.hostname])])])))
    # Create and configurate a spec section
    template = client.V1PodTemplateSpec(
        metadata=client.V1ObjectMeta(labels={"app": obj.name+node.hostname}),
        spec=client.V1PodSpec(restart_policy="Never", containers=[container],
                              affinity=affinity,
                              volumes=[volume01]
                              )
    )
    # Create the specification of deployment
    spec = client.V1JobSpec(
        template=template,
        backoff_limit=4)
    # Instantiate the job object
    job = client.V1Job(
        api_version="batch/v1",
        kind="Job",
        metadata=client.V1ObjectMeta(name=task_name),
        spec=spec)
    return job